import { svgToString } from "./objects/ObjectUtils";
import { SvgObject } from "./objects/StageObject";
import { useStage } from "./store/stage";
import { useSystem } from "./store/sys";

if (import.meta.env.MODE !== 'vscode') {
    (window as any).acquireVsCodeApi = () => { }
}

export namespace VscodeTools {
    export enum EditorOutputEvent {
        SAVE_FILE = 'saveFile',
        OPEN_FILE = 'openFile',
        UPDATE_FILE = 'updateFile',
        LOG = 'log',
        ENV_INFO = 'envInfo',
        EDITOR_READY = 'editorReady',
        NEW_FILE = 'newFile',
    }
    export enum EditorInputEvent {
        SET_CONTENT = 'setContent',
        SET_BASE_PATH = 'setBasePath',
        LOG = 'log',
    }
    export const vscode = acquireVsCodeApi();
    export async function init() {
        if (import.meta.env.MODE !== 'vscode') {
            return
        }
        console.log('init vscode tools')
        await callEnvMethod(EditorOutputEvent.EDITOR_READY)
        const info: any = await callEnvMethod(EditorOutputEvent.ENV_INFO)
        const { config } = useSystem()
        config.vip = info.vip
        config.baseUrl = info.path
        saveState('content', info.content)
        setContent(info.content)

        window.addEventListener('message', messageHandler);
    }

    export function setContent(content: string) {
        if (String(content).trim() === '') {
            return
        }
        console.log('set content')
        const stage = useStage()
        const svg = SvgObject.fromCode(content)
        stage.setSvg(svg)
    }

    export function callEnvMethod<T>(outType: EditorOutputEvent, data?: any): Promise<T> {
        return new Promise((resolve, reject) => {
            const handler = (event: MessageEvent) => {
                const { type } = event.data
                if (outType + '-res' === type) {
                    window.removeEventListener('message', handler)
                    resolve(event.data.data)
                }
            }
            if (import.meta.env.MODE === 'vscode') {
                vscode.postMessage({ type: outType, data });
            } else {
                window.dispatchEvent(new CustomEvent(outType, { detail: data }));
            }
            window.addEventListener('message', handler)
            setTimeout(() => {
                window.removeEventListener('message', handler)
                reject('timeout')
            }, 1000 * 5)
        })
    }

    export function updateFile(obj?: any) {
        if (import.meta.env.MODE !== 'vscode') {
            return
        }
        const { data } = useStage()
        const content = svgToString(obj || data.elements)
        if (String(content).trim() === '') {
            console.error('update content is empty')
            return
        }

        data.needSave = true
        console.log('update file')
    }

    export function saveFile(obj: any) {
        const { data } = useStage()
        data.needSave = false
        const content = svgToString(obj)
        if (String(content).trim() === '') {
            console.error('update content is empty')
            return
        }
        console.log('save file')
        return callEnvMethod(EditorOutputEvent.SAVE_FILE, content)
    }

    export function saveTextFile(content: string) {
        console.log('save file')
        return callEnvMethod(EditorOutputEvent.SAVE_FILE, content)
    }

    export function saveState(key: string, value: any) {
        if (String(value).trim() === '') {
            return
        }
        const state = vscode.getState() || {}
        state[key] = value
        vscode.setState(state)
    }

    export function checkVsState() {
        const previousState = vscode.getState();
        if (previousState) {
            setContent(previousState.content)
        }
    }

    export function newFile() {
        return callEnvMethod(EditorOutputEvent.NEW_FILE)
    }

    function messageHandler(event: MessageEvent) {
        const { type, data } = event.data
        switch (type) {
            case EditorInputEvent.SET_CONTENT:
                saveState('content', data.content)
                setContent(data.content)
                break

        }
    }

    export async function readClipBoard(){
        const txt = await navigator.clipboard.readText()
        return txt
    }
}